package beanstao.util.j2ee.request;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import beanstao.util.id.DId;
import beanstao.util.json.JsonLib;
import beanstao.util.store.KV;
import beanstao.util.store.domainobject.fields.PublicField;


/**
 * 一个对网页的访问命令所携带数据的几个类 ( HttpServletRequest , HttpSession ) 的封装。
 * 
 * @author beanstao@google.com 
 */
public class WebQD extends AbstractQD
{

	/**
	 * 类型的主方法。一般用来做测试使用。
	 * 
	 * @param args 方法的传入参数集合
	 */
	public static void main(final String[] args)
	{
	}

	protected static WebQD webQD = null;

	protected HttpServletRequest _Request = null;
	protected HttpSession _Session = null;

	public static WebQD ME()
	{
		if (webQD == null)
			return new WebQD();
		return webQD;
	}

	protected WebQD()
	{

	}

	WebQD(final HttpServletRequest request, final HttpSession session)
	{
		_Request = request;
		_Session = session;
	}

	/**
	 * @return 客户端的IP地址
	 */
	public InetAddress getClientIpAddress()
	{
		try
		{
			return InetAddress.getByName(_Request.getRemoteAddr());
		}
		catch (UnknownHostException e)
		{
		}
		return null;
	}

	/**
	 * 将页面提交的参数封装到HashMap中
	 * 
	 * @param request
	 * @param session
	 */
	boolean load()
	{
		if (this.verify(_Session))
		{
			_KeyValueMap.putAll(this.parseRequest(_Request));
			return _KeyValueMap != null;
		}
		return false;
	}

	public void loadBySessionIsNull()
	{
		this.logDebug("当用户登录时，无法检测HttpSession时，调用本方法：loadBySessionIsNull()获得数据。");
		_KeyValueMap = this.parseRequest(_Request);
	}

	/**
	 * 核心方法，分解Request中的参数
	 * 
	 * @param request
	 * @return
	 */
	private HashMap<String, KV> parseRequest(final HttpServletRequest request)
	{
		HashMap<String, KV> map = new HashMap<String, KV>();
		// 装配request范围内的参数
		if (request != null)
		{
			Enumeration<?> paramNames = request.getParameterNames();
			while (paramNames.hasMoreElements())
			{
				String paramName = (String) paramNames.nextElement();
				// Extjs自生成的参数
				if ("_dc".equals(paramName))
					continue;
				// 树节点自生成的参数
				if ("node".equals(paramName))
					continue;
				String[] paramValues = request.getParameterValues(paramName);
				if ("query".equals(paramName))
				{
					_QueryType = this.decodeParam(paramValues[0]);
					continue;
				}
				if (paramValues.length != 1)// 传递来的参数不能有重复
				{
					String message = String.format("%s 的值有多个，一般来讲传递来的参数有重复。忽略多出的参数。%s", paramName, JsonLib.fromObject(paramValues));
					this.logWarn(message);
				}
				String paramValue = this.decodeParam(paramValues[0]);
				KV kcv = KV.parse(paramName, paramValue);
				if (paramValue.length() != 0)
				{
					String name = paramName.toLowerCase();
					if (name.contains("-"))
						name = name.substring(name.lastIndexOf('-') + 1);
					map.put(name, kcv);
				}
			}

		}
		return map;
	}

	private boolean verify(final HttpSession session)
	{
		try
		{
			Object obj = session.getAttribute("loginname");
			if (obj != null)
			{
				_ModifyId = DId.ME(obj.toString());
				_KeyValueMap.put(PublicField.MODIFIOR, KV.ME(PublicField.MODIFIOR, _ModifyId));
				return true;
			}
			return false;
		}
		catch (Exception e)
		{
			this.logWarn("HttpSession 校验发生异常。", e);
			return false;
		}
	}

}
